﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Windows.Forms;

namespace FolderTransfer
{
    public class FolderClient
    {
        private TcpClient tcpClient;
        public BinaryReader Br { get; private set; }
        public BinaryWriter Bw { get; private set; }
        private FormMain formMain;
        private Server server;
        private Client client;

        public FolderClient(TcpClient tcpClient, FormMain formMain, Client client)
        {
            this.tcpClient = tcpClient;
            this.formMain = formMain;
            this.client = client;
            Br = new BinaryReader(tcpClient.GetStream());
            Bw = new BinaryWriter(tcpClient.GetStream());

            Thread recvThread = new Thread(RecvThread);
            recvThread.IsBackground = true;
            recvThread.Start();
        }
        public FolderClient(TcpClient tcpClient, FormMain formMain, Server server)
        {
            this.tcpClient = tcpClient;
            this.formMain = formMain;
            this.server = server;
            Br = new BinaryReader(tcpClient.GetStream());
            Bw = new BinaryWriter(tcpClient.GetStream());

            Thread recvThread = new Thread(RecvThread);
            recvThread.IsBackground = true;
            recvThread.Start();
        }

        private long totalLen;
        private string dirPath;
        private long haveRecvLen = 0L;
        private string folderName;
        private void RecvThread()
        {
            try
            {
                while (true)
                {
                    string cmd = Br.ReadString();
                    if (cmd == "AgreeOrNot")
                    {
                        folderName = Br.ReadString();
                        DialogResult result = MessageBox.Show("对方发送文件夹[" + folderName + "],请接收.", "温馨提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
                        if (result == DialogResult.Yes)
                        {
                            formMain.SetBtnEnabled("btnRecv", true);
                        }
                        else
                        {
                            SendString("Refuse");
                        }
                    }
                    else if (cmd == "Agree")
                    {
                        server.BeginSend();
                    }
                    else if (cmd == "Refuse")
                    {
                        MessageBox.Show("对方拒绝接收该文件夹.");
                    }
                    else if (cmd == "BeginTransfer")
                    {
                        Utils.watch.Reset();
                        Utils.watch.Start();
                        totalLen = Br.ReadInt64();
                    }
                    else if (cmd == "EndTransfer")
                    {
                        Utils.watch.Stop();
                        long ms = Utils.watch.ElapsedMilliseconds;
                        formMain.SetLable("tbStatus", "文件夹 [" + folderName + "] 接收完毕,用时: " + Utils.GetTime(ms) + ", 速度: " + Utils.GetSpeed(totalLen, ms) + ".");
                        //Console.WriteLine(msg);
                    }
                    else if (cmd == "FolderName")
                    {
                        dirPath = Br.ReadString();
                        if (client.RecvPath.EndsWith(@"\"))
                        {
                            dirPath = client.RecvPath + dirPath;
                        }
                        else
                        {
                            dirPath = client.RecvPath + "\\" + dirPath;
                        }
                    }
                    else if (cmd == "FileTransferBegin")
                    {
                        string fileName = Br.ReadString();
                        String filePath = "";
                        if (dirPath.EndsWith(@"\"))
                        {
                            filePath = dirPath + fileName;
                        }
                        else
                        {
                            filePath = dirPath + "\\" + fileName;
                        }
                        Console.WriteLine(filePath);
                        Directory.CreateDirectory(dirPath);
                        FileInfo file = new FileInfo(filePath);
                        FileStream fs = null;
                        if (!file.Exists)
                        {
                            fs = file.Create();
                        }
                        else
                        {
                            fs = file.Open(FileMode.Open, FileAccess.Write, FileShare.Read);
                        }
                        try
                        {
                            int readLength = Br.ReadInt32();
                            while (readLength != -1)
                            {
                                byte[] bs = Br.ReadBytes(readLength);
                                fs.Write(bs, 0, readLength);//写入文件
                                fs.Flush();
                                haveRecvLen += readLength;
                                readLength = Br.ReadInt32();
                                String msg = "传送进度: " + (haveRecvLen * 100 / totalLen) + " %";
                                formMain.SetLable("tbStatus", msg);
                                //Console.WriteLine(msg);
                            }
                            fs.Flush();
                            fs.Close();
                        }
                        catch (Exception ee)
                        {
                            Console.WriteLine("文件接收时异常：" + ee.Message);
                        }
                    }
                }
            }
            catch (Exception ee)
            {
                Console.WriteLine(ee.Message);
            } 
        }

        public void SendString(string msg)
        {
            try
            {
                Bw.Write(msg);
                Bw.Flush();
            }
            catch(Exception e)
            {
                Console.WriteLine(e.Message);
            }    
        }

        public void SendLong(long totalLen)
        {
            try
            {
                Bw.Write(totalLen);
                Bw.Flush();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }

        public void SendBytes(byte[] buffer, int readLen)
        {
            try
            {
                Bw.Write(readLen);
                Bw.Write(buffer, 0, readLen);
                Bw.Flush();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }

        public void SendInt(int value)
        {
            try
            {
                Bw.Write(value);
                Bw.Flush();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
    }
}
